home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
serien
/
purity
/
nr.12
/
workshop
/
pascalkursi.txt
< prev
next >
Wrap
Text File
|
1995-04-21
|
18KB
|
421 lines
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Systemprogrammierung in PCQ-Pascal +
+ Kurs für AMIGAGadget und Purity- Teil I +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Viele kennen Turbo Pascal vom PC. Mit dem PCQ-Compiler von der Fish-Disk
503 steht nun auf dem Amiga ein billiger und leistungsfähiger Pascal-
Compiler zur Verfügung. Nun ist der grundsätzliche Iso-Standard
implementiert, die Systemprogrammierung stellt aber PC-Programmierer
vor ein Rätsel. Deshalb nun - ein Kurs ! (Tusch...)
Der kann natürlich auch mit der PCQ Version 1.1 durchgeführt werden, aber
hauptsächlich wegen der Includefiles empfiehlt sich Version 1.2.
I. Voraussetzungen
Um diesem Kurs folgen zu können, sollte man sich mit dem CLI auskennen.
Außerdem brauchte man den PCQ-Compiler inklusive dem Assembler A68k
und dem BLink. Mit diesen sollte man sich auch auskennen (notfalls im
DOC-File von PCQ nachlesen). Als erstes stelle man sich eine bootfähige
Pascaldisk zusammen. Der Pcq kommt als "Pascal" in den C-Ordner, wohin
ihm der A68k und BLink folgen. Die PCQ.Lib kommt einfach in das
Rootdirectory (man könnte auch ein eigenes Libraries-Subdirectory
erstellen, aber bei einer Library lohnt sich das kaum...). Desweiteren
benötigen wir noch den Include-Ordner und einen ASCII-Editor (es
empfiehlt sich der DME). Das war's schon an Voraussetzungen.
Nun kann's losgehen.
II. Screens und Windows
Wie aus der Überschrift erkennbar, soll es unsere erste Aufgabe sein,
erstmal einen eigenen Bildschirm zu öffnen. Nun gibt es auf dem Amiga
verschiedene Programme, die sich um bestimmte Aufgabenteile kümmern,
die sogenannten "Libraries". Bevor man sich an ihren Routinen gütlich
tun kann, muß man sie erstmal öffnen. Nun brauchen wir, um einen
Screen zu öffnen, natürlich nicht alle Libraries, sondern nur die
sogenannten "Intuition.Library". Sie kümmert sich um Fenster,
Bildschirme, Menüleisten und Gadgets (da gibt's kein deutsches Wort,
das passt...oder ?). Und - wie schön für uns - da der Startupcode
von PCQ-Pascal diese Library schon benötigt, brauchen wir sie noch
nicht einmal mehr von Hand aufzumachen. Auf alle von ihr zur Verfügung
gestellten Routinen können wir in einem PCQ-Programm ohne Umstände
zurückgreifen. (Na ja, das wird später noch eingeschränkt....
wartet's ab.) Ein's muß man aber doch tun : das File "Intuition.I"
in den Programmcode einbinden. Das geht ganz einfach : mit dem
Compilerbefehl ($I "Include:Intuition/Intuition.I" }. Er öffnet ein File,
in dem diverse Strukturen zur Verwaltung von Strukturen des Systems
enthalten sind.
Unser Programm sieht also so aus :
Program IntuitionTest (input , output);
{ Listing für den AMIGAGadget/Purity - Pascalkurs , Grundgerüst }
{$I "Include:Intuition/Intuition.I" }
BEGIN
END.
Was macht das Programm ? Antwort : nichts, da der Programmblock leer
ist. Allerdings ist es ein Gerüst, in das man beliebige Intuition-
operationen einbauen kann. Um einen Bildschirm zu öffnen, muß man die
Funktion "OpenScreen" aufrufen. Sie benötigt als Parameter die Addresse
einer NewScreen-Struktur, in der die Daten für den zu erstellenden
Bildschirm enthalten sind. Der Wert, den sie zurückliefert ist
entweder Null (=NIL), wenn der Versuch, den Bildschirm zu öffnen,
fehlgeschlagen ist (passiert bei uns nicht !!! Oder MEISTENS nicht...)
oder ein Zeiger auf eine Screenstruktur, die die Daten des geöffneten
Bildschirms enthält.
Wie sieht nun diese NewScreen-Struktur aus ? Antwort : so :
NewScreen = record
LeftEdge, linke Ecke des Screens (meistens 0)
TopEdge, obere Ecke des Screens (meistens 0)
Width, Breite des Screens (mstns. 320 o. 640)
Height, Höhe des Screens (mstns. 256 o. 512)
Depth : Short; Anzahl der Bitplanes (siehe A 1)
DetailPen, Registernummer des Zeichenstifts (A 2)
BlockPen : Byte; Registernummer des Blockstifts (A 2)
ViewModes : Short; legt den sogenannten ViewPort fest (A 3)
SType : Short; Art des Screens (A 4)
Font : Address; Zeiger auf den Schriftsatz (mstns. Nil)
DefaultTitle : String; Zeiger auf den Titel des Screens
Gadgets : Address; Zeiger auf Screengadgets (unwichtig)
CustomBitMap : Address; Zeiger auf selbstgemachte BitMap (mstns. Nil)
end;
A 1 : Um die Anzahl der Farben zu bestimmen, muß man sogenannte
Bitplanes verwenden. Diese kann man sich in etwa als große
rechteckige "Bitflächen" vorstellen.
+-------------------+ Um dies zu verstehen, muß man sich
| | mit der Art und Weise befassen, in der
| | der Amiga seine Grafik darstellt.
| | Dies funktioniert, indem jedem Punkt
| | des Bildschirms ein Bit pro
+-------------------+ Bitplane zugeordnet ist.
Ein Bildpunkt kann nun pro Bitplane also zwei Zustände
annehmen : Bit gesetzt und Bit nicht gesetzt.
Bei einer Bitplane kann es also nur zwei Arten von
Bildpunkten geben : 0 (Bit in Bitplane nicht gesetzt)
und 1. Was sollen nun diese Zahlen ?? Was bestimmen sie ?
Ganz einfach : pro Bildschirm stellt der Amiga eine
bestimmte Anzahl von Farben zur Verfügung (nämlich exakt
zwei hoch Anzahl der Bitplanes, in unserem Falle 2 hoch 1=2).
Diese sind von 0 bis (2^Anzahl)-1 durchnummeriert, bei uns
also 0 und 1. Aha !!! Die Bits der Bitplane zeigen also auf
das Farbregister, mit dem der entsprechende Bildpunkt
eingefärbt wird. Nun legen wir auf diese eine Bitplane noch
eine zweite drauf. Betrachtet wir einen Ausschnitt :
1.Bitplane : 001001110010
2.Bitplane : 010000110101
Man sieht, es gibt vier Kombinationsmöglichkeiten :
(die erste Zahl ist die höchste Bitplane)
00 , 01 , 10 , 11 - Binärzahlen. Ich gehe mal davon aus, daß
jeder mit ihnen umgehen kann. Dezimal geschrieben gibt es also
folgende Zuweisungsmöglichkeiten bei 2 Bitplanes :
0 , 1 , 2 , 3. Man ahnt schon, was diese Zahlen bedeuten :
sie kennzeichnen das Register (den Farbtopf), aus dem der
Amiga die Farbe zur Darstellung des entsprechenden Bildpunktes
schöpfen muß. Und zuguterletzt noch die Variante mit
3 Bitplanes :
1.BP : 001001110010
2.BP : 010000110101
3.BP : 010101101010
Und schupdiwupp, da sind es acht Kombinationsmöglichkeiten :
000 , 001 , 010 , 011 , 100 , 101 , 110 , 111 - dezimal 0-7.
Und so weiter...
Quintessenz : Will man einen Screen mit 16 Farben, dann nehme
man für Depth den Wert 4 (2^4 = 16). Für 32 muß man 5 Bitplanes
wählen.
A 2 : Diese Zahlen beziehen sich auf das in A 1 angesprochene
Farbregister (0 - (2^Anzahl Bitplanes)-1).
A 3 : Ein Screen ist ein Element, das relativ weit entfernt vom System
ist. Weiter unten ist die sogenannte View-Struktur zu finden.
"Auf ihr drauf" liegen ViewPorts, die man besser modifizieren
kann als Views. "Auf denen" findet man nun RastPorts, welche
wieder Teile von Screens sind, die wiederrum "unter" Windows
liegen, welche den Inbegriff der Manipulationsfreundlichkeit
darstellen. Nun sehen Standardviewports für Screens eine
maximale horizontale Auflösung von 320 Pixeln und eine
vertikale von 256 Pixeln vor. Um dies zu ändern, muß man
das Feld ViewModes mit diversen Werten belegen. Diese sind
in "Include:Graphics/View.I" (wird von Intuition.I mit einge-
lesen) vordefiniert. So gibt es z.B. HIRES (erlaubt 640 Pixel
horizontal) und LACE (aktiviert den sogenannten Interlace-Modus,
welcher über einen Trick 512 vertikale Pixel erlaubt).
A 4 : Es gibt zwei Arten von Screen : den CUSTOMSCREEN_f (wird in
"include:Intuition/Intuition.i" definiert). Er ist sehr praktisch
und wird auch meistens verwendet. Nachteil : sollten Sys-Requester
(kennt jeder : "Disk is NOT a DOS Disk" , "Read/Write error",
"No Disk present in", etc..) geöffnet werden, so wird der
Workbenchscreen in den Vordergrund geschaltet, was
verständlicherweise nicht besonders professionell wirkt.
Die Alternative ist WBENCHSCREEN_f. Hier werden System-Requester
auf dem Screen geöffnet. Traumhaft. Nachteil : man kriegt
Probleme, wenn man in der Farbstruktur der Preferences
rumpfuscht und wenn man aus Versehen den "alten" Workbenchscreen
in den Vordergrund geschaltet hat und das eigene Programm
öffnet plötzlich ein Fenster, dann erscheint dies auf dem
"alten" Screen....
Also gut, hauen wir einen Screen auf.
Program IntuitionTest (input , output);
{ Listing für den AMIGAGadget/Purity - Pascalkurs , Screen öffnen }
{$I "Include:Intuition/Intuition.I" }
VAR
myscreen : ScreenPtr;
PROCEDURE CloseDisplay;
{ Sollte ein Teil des Displays offen sein, dann wird er von }
{ dieser Routine geschlossen. }
BEGIN
IF myscreen<>NIL THEN CloseScreen (myscreen);
END;
PROCEDURE BreakProgram (reason : STRING);
{ Diese Routine schließt alles bisher geöffnete, druckt den }
{ Fehlergrund aus und bricht dann das Programm ab. }
BEGIN
CloseDisplay;
WRITELN ('Program error : ',reason);
Exit (42);
END;
PROCEDURE OpenDisplay;
{ Diese Routine erstellt ein Display. }
CONST
mynewscreen : NewScreen = (0,0,640,256,2,0,1,HIRES,
CUSTOMSCREEN_f,NIL,
"Unser erster Screen",NIL,NIL);
BEGIN
myscreen := OpenScreen (Adr(mynewscreen));
IF myscreen=NIL THEN BreakProgram ("Couldn't open Screen");
END;
PROCEDURE WarteEinWenig;
{ Eine unelegante Routine, die nur dazu dient,das geöffnete }
{ Display zu betrachten. In späteren Programmen, wird sie }
{ durch eleganteren Stuff ersetzt. }
VAR ww1 , ww2 : INTEGER;
BEGIN
FOR ww1:=1 TO 100 DO
FOR ww2:=1 TO 2000 DO;
END;
BEGIN
OpenDisplay;
WarteEinWenig;
CloseDisplay;
END.
Alles klar ?? Nun gut, wenden wir uns dem Window zu. Prinzipiell
funktioniert die Sache wie mit dem Screen : NewWindowStruktur
an OpenWindow übergeben, Zeiger auf WindowStruktur zurückerhalten.
Also schnell der Blick auf die NewWindow-Struktur :
NewWindow = record
LeftEdge,
TopEdge,
Width,
Height : Short;
DetailPen,
BlockPen : Byte; siehe NewScreen-Struktur
IDCMPFlags : Integer; siehe B 1
Flags : Integer; siehe B 2
FirstGadget : Address; Zeiger auf das erste Gadget
CheckMark : Address; unwichtig
Title : String; Zeiger auf Titel des Windows
Screen : Address; Zeiger auf den Screen
BitMap : Address; Zeiger auf eigene BitMap
MinWidth, siehe B 2
MinHeight,
MaxWidth,
MaxHeight : Short;
WType : Short; siehe SType bei NewScreen
end;
B 1 : Der IDCMP-Port ist die Brücke zwischen dem Benutzer und
Intuition. Hier wird dem Programmierer mitgeteilt, was der
Anwender mit Intuition vorhat. Dies beinhaltet so Sachen wie
Mausknopf gedrückt , Window geschlossen , etc. . Hiermit
beschäftigen wir uns in der nächsten Folge im Kapitel
Messages.
B 2 : Hier werden einige grundlegende Eigenschaften des Windows
festgelegt. Definiert in "Intuition.I" sind folgende :
WINDOWSIZING : die Größe des Windows kann verändert werden.
Maximum sowie Minimum der Windowgröße kann
in den Feldern MinWidth,MinHeight,MaxWidth
und MaxHeight festgelegt werden.
WINDOWDRAG : man kann das Window durch die Gegend ziehen.
WINDOWDEPTH : das Window bekommt Gadgets, mit denen man es
hinter andere Windows schalten kann.
WINDOWCLOSE : das Window erhält in der linken oberen
Ecke ein Closegadget. Abfragen muß man es aber
selber - wartet auf die nächste Folge.
SIZEBRIGHT und
SIZEBBOTTOM : treffen unwesentliche Aussagen über den Ort
des WindowSizing-Gadgets
SMART_REFRESH : der Amiga merkt sich in einem Speicherbereich,
den er extra reserviert, Teile des Fensterinhalts,
wenn dieses von anderen Fenstern überlagert
wird. Normalerweise verwendet man diesen Modus.
SIMPLE_REFRESH : Man erhält nur eine Message (nächste Folge !!!),
wenn der Fensterinhalt wieder erneurt werden muß
(da z.B. ein Filerequester Teile des Fensters
überlagert hatte). Um den Vorgang an sich muß man
sich aber selbst kümmern...
SUPER_BITMAP : sehr speicherintensive Refreshalternative. Ein
Speicherbereich im Amiga enthält den gesamten
Fensterinhalt. Das dargestellte Window kann auch
nur ein Ausschnitt aus dieser "SuperBitmap" sein..
OTHER_REFRESH : na ja...
BACKDROP : ganz tolles Flag : das Window ist immer hinter
allen anderen Windows des Screens
REPORTMOUSE_f : Intuition speichert die aktuellen Mauskoordinaten
in den Feldern MouseX und MouseY der
Windowstruktur.
GIMMEZEROZERO : Intuition betrachtet den Inhalt des Fensters
getrennt von den äußeren Applikationen (Rahmen,
Gadgets, etc.)
BORDERLESS : das Fenster bekommt keinen Rahmen
ACTIVATE : das Fenster wird nach dem Öffnen gleich aktiviert
WINDOWACTIVE : das Fenster ist das gerade aktive
INREQUEST : das Fenster ist im Requester-Modus
MENUSTATE : die Menuleiste ist heruntergeklappt
RMBTRAP : der rechte Mausknopf wird wie der linke behandelt
+ einige absolut unwichtige
Genug der grauen Theorie - öffnet das Fenster !!!
Program IntuitionTest (input , output);
{ Listing für den AMIGAGadget/Purity - Pascalkurs , }
{ Screen+Window öffnen }
{$I "Include:Intuition/Intuition.I" }
VAR
myscreen : ScreenPtr;
mywindow : WindowPtr;
PROCEDURE CloseDisplay;
{ Sollte ein Teil des Displays offen sein, dann wird er von }
{ dieser Routine geschlossen. }
BEGIN
IF myscreen<>NIL THEN
CloseScreen (myscreen);
IF mywindow<>NIL THEN
CloseWindow (mywindow);
END;
PROCEDURE BreakProgram (reason : STRING);
{ Diese Routine schließt alles bisher geöffnete, druckt den }
{ Fehlergrund aus und bricht dann das Programm ab. }
BEGIN
CloseDisplay;
WRITELN ('Program error : ',reason);
Exit (42);
END;
PROCEDURE OpenDisplay;
{ Diese Routine erstellt ein Display. }
CONST
mynewscreen : NewScreen = (0,0,640,256,2,0,1,HIRES,
CUSTOMSCREEN_f,NIL,
"Unser zweiter Screen",NIL,NIL);
mynewwindow : NewWindow = (0,0,400,200,0,1,0,
SMART_REFRESH+ACTIVATE+
WINDOWDRAG,NIL,NIL,"Unser erstes Fenster",
NIL,NIL,0,0,0,0,CUSTOMSCREEN_f);
BEGIN
myscreen := OpenScreen (Adr(mynewscreen));
IF myscreen=NIL THEN BreakProgram ("Couldn't open Screen");
mynewwindow.Screen:=myscreen;
mywindow := OpenWindow (Adr(mynewwindow));
IF mywindow=NIL THEN BreakProgram ("Couldn't open Window");
END;
PROCEDURE WarteEinWenig;
{ Eine unelegante Routine, die nur dazu dient,das geöffnete }
{ Display zu betrachten. In späteren Programmen, wird sie }
{ durch eleganteren Stuff ersetzt. }
VAR ww1 , ww2 : INTEGER;
BEGIN
FOR ww1:=1 TO 500 DO
FOR ww2:=1 TO 2000 DO;
END;
BEGIN
OpenDisplay;
WarteEinWenig;
CloseDisplay;
END.
So, das war's für heute. Probiert schön fleißig mal mit allen
möglichen Window- und Screentypen herum.
Sollte es Probleme oder Fragen geben, so wendet Euch mit einem
Leserbrief an die Purity oder direkt an mich
Andreas Neumann
Auf dem Ruhbühl 151
W 7997 Immenstaad
Tel.: 07545 / 3483
Übrigens : alle Routinen, die wir hier in dem Kurs entwickeln, können
ruhig in eigene Programme übernommen werden. Ein Hinweis auf diesen
tollen Kurs von mir wäre aber ganz nett.
Viel Spaß und bis zur nächsten Purity, in dem es wieder heißt
"END. gut , alles gut."
© 14.09.1991 by Andreas Neumann für AmigaGadget von Nils Kassube
und Purity von Steppenbrand und Diesel